package org.hackystat.devcathlon.ui.page.teams.profile;

import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.list.PageableListView;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.hackystat.devcathlon.engine.match.Match;
import org.hackystat.devcathlon.engine.match.MatchManager;
import org.hackystat.devcathlon.engine.team.Team;
import org.hackystat.devcathlon.ui.DevcathlonApplication;
import org.hackystat.devcathlon.ui.DevcathlonSession;
import org.hackystat.devcathlon.ui.page.matches.MatchDetailPage;
import org.hackystat.devcathlon.ui.page.matches.MatchesSession;
import org.hackystat.devcathlon.ui.page.teams.TeamsSession;

/**
 * The matches panel for the team profile page.
 * @author John Ly
 *
 */
public class TeamMatchesPanel extends Panel {
  
  /** Supports serialization. */
  private static final long serialVersionUID = 1L;

  /**
   * Creates the panel for matches on the team profile.  
   * Includes the team's win record.
   * 
   * @param id The wicket id tag for the panel component.
   */
  public TeamMatchesPanel(String id) {    
    super(id);    
    
    PageableListView listView = new PageableListView("Matches", getInvolvedMatches(), 4) {
      private static final long serialVersionUID = 1L;

      @Override
      protected void populateItem(final ListItem matchItem) {
        final String matchName = (String) matchItem.getModelObject();
        matchItem.add(new Label("MatchName", matchName));
        
        Link matchPageLink = new Link("MatchPageLink") {
          private static final long serialVersionUID = 1L;

          @Override
          public void onClick() {
            try {
              setResponsePage(new MatchDetailPage(matchName));
            }
            catch (Exception e) {
              ((DevcathlonApplication)this.getApplication()).getLogger().
              info(e.getMessage());
            }
          }          
        };
                
        Match match = MatchManager.getInstance().getMatch(matchName);
        String matchStatus = "In Progress";
        if (match.isCompleted()) {
          matchStatus = "Final";          
        }
        Label matchStatusLabel = new Label("MatchStatus", matchStatus);
        
        matchPageLink.add(matchStatusLabel);
        matchItem.add(matchPageLink);
        
        

        MatchesSession matchSession = DevcathlonSession.get().getMatchesSession();
        final List<Team> teams = new ArrayList<Team>(matchSession.getMatch(matchName).getTeams());
        ListView teamsInMatch = new ListView("Teams", teams) {
          private static final long serialVersionUID = 1L;

          @Override
          protected void populateItem(ListItem teamItem) {
            Match match = MatchManager.getInstance().getMatch(matchName);
            Team team = (Team) teamItem.getModelObject();                        
            Label teamNameLabel = new Label("TeamName", team.getName());

            MatchesSession matchSession = DevcathlonSession.get().getMatchesSession();
            Integer teamPoints = matchSession.getMatch(matchName).getTeamPoints(team);
            Label teamPointsLabel = new Label("TeamPointsLabel", teamPoints.toString());

            
            if (match.isCompleted() && match.getWinningTeams().contains(team.getName())) {
              teamNameLabel.add(new SimpleAttributeModifier("style", "font-weight:bold"));
              teamPointsLabel.add(new SimpleAttributeModifier("style", "font-weight:bold"));
              
            }
            teamItem.add(teamNameLabel);
            teamItem.add(teamPointsLabel);            
          }          
        };
        
        matchItem.add(teamsInMatch);     
        
        matchItem.add(new AttributeModifier("class", true, new AbstractReadOnlyModel() {
          private static final long serialVersionUID = 1L;

          public Object getObject() {
              return (matchItem.getIndex() % 2 == 0) ? "odd" : "even";
          }
      }));

      }      
    };   
    add(listView);
    add(new PagingNavigator("MatchNavigator", listView));
    add(new Label("TeamRecord", calculateWinRecord()));
  }
  

  /**
   * Retrieves all the matches involving the current team.
   * @return The list of matches.
   */
  private List<String> getInvolvedMatches() {
    TeamsSession session = DevcathlonSession.get().getTeamsSession();
    MatchesSession matchSession = DevcathlonSession.get().getMatchesSession();
    List<String> allMatches = matchSession.getMatchNames();
    List<String> involvedMatches = new ArrayList<String>();
    
    for (String matchName : allMatches) {
      for (Team team : matchSession.getMatch(matchName).getTeams()) {
        if (team.getName().equals(session.getSelectedTeam())) {
          involvedMatches.add(matchName);
        }
      }
    }
    return involvedMatches;
  }
  
  /**
   * Calculate the team's winning record and returns it in a sring.
   * @return The record in the form wins-loss-tie
   */
  private String calculateWinRecord() {
    TeamsSession session = DevcathlonSession.get().getTeamsSession();
    String teamName = session.getSelectedTeam();    
    Match match;     
    int wins = 0;
    int loss = 0;
    int tie = 0;     
    for (String matchName : getInvolvedMatches()) {
      match = MatchManager.getInstance().getMatch(matchName);  
      if (match.isCompleted()) {
        if (match.getWinningTeams().size() > 1) {
          tie++;
        }
        else if (match.getWinningTeams().contains(teamName)) {
          wins++;
        }
        else {
          loss++;
        }
      }
    }
    return wins + "-" + loss + "-" + tie;    
  }
  
}
